vue-router 动态路由之权限控制

MuYan2021-09-15VueVue

vue 项目的路由权限控制处理方法,借助于 vuex、vue-router 实现,因为每个人的需求不一致等问题,所以以下信息仅供参考。

// router/router.js
/**
 * 动态路由
 * @type { *[] }
 */
export const asyncRouterMap = [
  {
    path: "/",
    name: "index",
    component: import("@/*******"),
    redirect: "/home",
    children: [
      {
        path: "/home",
        name: "home",
        component: import("@/*******"),
        meta: {
          title: "首页",
        },
        children: [
          {
            path: "/home",
            name: "home",
            component: () => import("@/*******"),
            meta: {
              title: "首页",
            },
          },
        ],
      },
      {
        path: "/news",
        name: "news",
        component: import("@/*******"),
        meta: {
          title: "新闻列表页",
        },
        redirect: "/course/individualList",
        children: [
          {
            path: "/news/list",
            name: "newsList",
            component: () => import("@/*******"),
            meta: {
              title: "列表页",
            },
          },
          {
            path: "/news/edit",
            name: "newsEdit",
            component: () => import("@/*******"),
            meta: {
              title: "编辑页",
              permission: ["admin"], // 定义权限
            },
          },
        ],
      },
    ],
  },
];

/**
 * 基础路由
 * @type { *[] }
 */
export const constantRouterMap = [
  {
    path: "/user",
    component: () => import("@/******"),
    redirect: "/user/login",
    hidden: true,
    children: [
      {
        path: "login",
        name: "login",
        component: () => import("@/*******"),
      },
    ],
  },
];
// router/index.js
import Vue from "vue";
import Router from "vue-router";
import { constantRouterMap } from "./router.js";

Vue.use(Router);

export default new Router({
  mode: "history",
  routes: constantRouterMap,
});
// store/module/permission.js
import { asyncRouterMap, constantRouterMap } from "@/router/router.js";
import router from "@/router";

// 权限校验
function hasPermission(permission, route) {
  if (
    route.meta &&
    route.meta.permission &&
    Array.isArray(route.meta.permission)
  ) {
    return route.meta.permission.some((e) => {
      return permission.includes(e);
    });
  }
  return false;
}

// 路由过滤
function filterAsyncRouter(routerMap, permissions) {
  const accessedRouters = routerMap.filter((route) => {
    if (hasPermission(permissions, route)) {
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children, permissions);
      }
      return true;
    }
    return false;
  });
  return accessedRouters;
}

const permission = {
  state: {
    routes: constantRouterMap,
    addRouters: [],
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers;
      state.routes = routers.concat(constantRouterMap);
      router.addRoutes(routers);
    },
  },
  actions: {
    GenerateRoutes({ commit }) {
      return new Promise(async (resolve) => {
        // 以下内容仅供参考,实际内容根据自己项目自定义
        // 当前登录者权限 admin
        const level = "admin";
        if (["admin"].includes(level)) {
          // admin 为最高权限,所以不做限制
          commit("SET_ROUTERS", asyncRouterMap);
        } else {
          const initRouter = JSON.parse(JSON.stringify(asyncRouterMap));
          const newRouter = filterAsyncRouter(initRouter, level);
          commit("SET_ROUTERS", newRouter);
        }
        resolve();
      });
    },
  },
};

export default permission;
// store/getters.js
const getters = {
  addRouters: (state) => state.permission.addRouters,
};

export default getters;
// router/permission.js
import router from "./router";
import store from "./store";

const loginRoutePath = "/user/login"; // 登录页面
const defaultRoutePath = "/home"; // 默认页面
router.beforeEach((to, from, next) => {
  let token = sessionStorage.getItem("token");
  if (token) {
    // 已登录
    if (to.path === loginRoutePath) {
      next({ path: defaultRoutePath });
    } else {
      if (!store.getters.addRouters.length) {
        store.dispatch("GenerateRoutes").then(() => {
          // 请求带有 redirect 重定向时,登录自动重定向到该地址
          const redirect = decodeURIComponent(from.query.redirect || to.path);
          if (to.path === redirect) {
            next({ ...to, replace: true });
          } else {
            // 跳转到目的路由
            next({ path: redirect });
          }
        });
      } else {
        next();
      }
    }
  } else {
    next(loginRoutePath); // 全部重定向到登录页
  }
});
  • 全局引入
// main.js
import store from "./store";
import router from "./router";
import "./router/permission";

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8